﻿#ifndef __UIBASE_H__
#define __UIBASE_H__


#pragma once

namespace DuiLib {
	/////////////////////////////////////////////////////////////////////////////////////
	//

#define UI_WNDSTYLE_CONTAINER  (0)
#define UI_WNDSTYLE_FRAME      (WS_VISIBLE | WS_OVERLAPPEDWINDOW)
#define UI_WNDSTYLE_CHILD      (WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
#define UI_WNDSTYLE_DIALOG     (WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)

#define UI_WNDSTYLE_EX_FRAME   (WS_EX_WINDOWEDGE)
#define UI_WNDSTYLE_EX_DIALOG  (WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME)

#define UI_CLASSSTYLE_CONTAINER  (0)
#define UI_CLASSSTYLE_FRAME      (CS_VREDRAW | CS_HREDRAW)
#define UI_CLASSSTYLE_CHILD      (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)
#define UI_CLASSSTYLE_DIALOG     (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)


	/////////////////////////////////////////////////////////////////////////////////////
	//
#ifndef ASSERT
#define ASSERT(expr)  _ASSERTE(expr)
#endif

#ifdef _DEBUG
#ifndef DUITRACE
#define DUITRACE DUI__Trace
#endif
#define DUITRACEMSG DUI__TraceMsg
#else
#ifndef DUITRACE
#define DUITRACE
#endif
#define DUITRACEMSG _T("")
#endif

	void UILIB_API DUI__Trace (LPCTSTR pstrFormat, ...);
	LPCTSTR UILIB_API DUI__TraceMsg (UINT uMsg);

	/////////////////////////////////////////////////////////////////////////////////////
	//

	class UILIB_API CNotifyPump {
	public:
		bool AddVirtualWnd (faw::string_view_t strName, CNotifyPump* pObject);
		bool RemoveVirtualWnd (faw::string_view_t strName);
		void NotifyPump (TNotifyUI& msg);
		bool LoopDispatch (TNotifyUI& msg);
		DUI_DECLARE_MESSAGE_MAP ()
	private:
		CStdStringPtrMap m_VirtualWndMap;
	};

	class UILIB_API CWindowWnd {
	public:
		CWindowWnd ();

		HWND GetHWND () const { return m_hWnd; }
		bool RegisterWindowClass ();
		bool RegisterSuperclass ();

		HWND Create (HWND hwndParent, faw::string_view_t pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
		HWND Create (HWND hwndParent, faw::string_view_t pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
		HWND CreateDuiWindow (HWND hwndParent, faw::string_view_t pstrWindowName, DWORD dwStyle = 0, DWORD dwExStyle = 0);
		HWND Subclass (HWND hWnd);
		void Unsubclass ();
		void ShowWindow (bool bShow = true, bool bTakeFocus = true);
		UINT ShowModal ();
		void Close (UINT nRet = IDOK);
		void CenterWindow ();	// 居中，支持扩展屏幕
		void SetIcon (UINT nRes);

		LRESULT SendMessage (UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
		LRESULT PostMessage (UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
		void ResizeClient (int cx = -1, int cy = -1);

	protected:
		virtual faw::string_view_t GetWindowClassName () const = 0;
		virtual faw::string_view_t GetSuperClassName () const { return _T (""); }
		virtual UINT GetClassStyle () const { return 0; }

		virtual LRESULT HandleMessage (UINT uMsg, WPARAM wParam, LPARAM lParam);
		virtual void OnFinalMessage (HWND hWnd);

		static LRESULT CALLBACK __WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
		static LRESULT CALLBACK __ControlProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

	protected:
		HWND m_hWnd;
		WNDPROC m_OldWndProc;
		bool m_bSubclassed;
	};

} // namespace DuiLib

#endif // __UIBASE_H__
